//
//  SpellSubviewController.m
//  This file is part of D&D Manager
//
//  Created by Matthew Hutton on 11/02/2007.
//
//
//D&D Manager, a D&D Character and battle management program.
//Copyright (C) 2007, Matthew Hutton
//
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License along with this program; if not, write to:
//The Free Software Foundation, Inc.,
//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#import "SpellSubviewController.h"
#import "SpellMethods.h"
#import "FeatActions.h"
#import "AbilityChanged.h"

@implementation SpellSubviewController
//-(id)initFromAppController:(AppController *)theAppController{
-(id)initWithCharController:(NSArrayController *)cCont
		withSpellController:(NSArrayController *)sCont
			withCharTabView:(NSTabView *)tabView{
	[super init];
	//NSLog(@"spell subviews created");
	[NSBundle loadNibNamed:@"SpellSubviews"
					 owner:self];
	charController=cCont;
	spellController=sCont;
	characterTabView=tabView;
	memorisedWasSelected=NO;
	mObjC=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
	model=[[mObjC persistentStoreCoordinator] managedObjectModel];
	return self;
}
-(NSManagedObjectContext *)managedObjectContext{
	if(mObjC==nil){
		mObjC=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
	}
	return mObjC;
}
-(void)processAddToSpellbookButton{
	if([self numberOfRowsInTableView:availableSpellsTable]==0){
		[addToSpellbookButton setEnabled:NO];
	}else{
		//check if selected item in currentCharacters, first get it.
		//*******CONTINUE WORK HERE*******
		NSManagedObject *availableSpell=[availableSpells objectAtIndex:[availableSpellsTable selectedRow]];
		//now check if it is in the current characters spell list.
		if([currentCharactersSpellClasses containsObject:availableSpell]){
			[addToSpellbookButton setEnabled:NO];
		}else{
			[addToSpellbookButton setEnabled:YES];
		}
	}
}
-(void)processingCharacter:(NSManagedObject *)obj
	  withCharacterClass:(NSManagedObject *)characterClass{
	if([spellOptionsTabs indexOfTabViewItem:[spellOptionsTabs selectedTabViewItem]]==0){
		[self processSpellBasicsForCharacterClass:characterClass
									 forCharacter:obj];
		if([obj valueForKey:@"domain1"]!=nil){
			//NSLog(@"domain1 index=%d",index);
			[domainMenu1 selectItemWithTitle:[obj valueForKey:@"domain1"]];
			//NSLog(@"domainMenu1.title=%@",[domainMenu1 titleOfSelectedItem]);
		}else{
			[domainMenu1 selectItemWithTitle:@"Choose..."];
		}
		if([obj valueForKey:@"domain2"]!=nil){
			[domainMenu2 selectItemWithTitle:[obj valueForKey:@"domain2"]];
		}else{
			[domainMenu2 selectItemWithTitle:@"Choose..."];
		}
		if([obj valueForKey:@"domain3"]!=nil){
			[domainMenu3 selectItemWithTitle:[obj valueForKey:@"domain3"]];
		}else{
			[domainMenu3 selectItemWithTitle:@"Choose..."];
		}
		[spellSaveModTF setIntValue:[[obj valueForKey:@"spellSaveModifier"] intValue]];
		[spellPenetrationTF setIntValue:[[obj valueForKey:@"spellPenetration"] intValue]];
		return;
	}
	if([spellOptionsTabs numberOfTabViewItems]==2){
		[self processSpellbookForCharacterClass:characterClass
								   forCharacter:obj];
	}else{
		if([spellOptionsTabs indexOfTabViewItem:[spellOptionsTabs selectedTabViewItem]]==1){
			[self setupMemorised:memorisedSpellsTabs
						 forChar:obj
						forClass:characterClass];
		}else{
			[self processSpellbookForCharacterClass:characterClass
									   forCharacter:obj];
		}
	}
}
-(void)processSpellBasicsForCharacterClass:(NSManagedObject *)characterClass
							  forCharacter:(NSManagedObject *)obj{
	[self setupDomainsList];
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
		[domainSpells setHidden:NO];
		[noOfDomainSpells setHidden:NO];
		NSRect rect=[spellsPerDayBox frame];
		rect.size.width=288;
		[spellsPerDayBox setFrame:rect];
		[domainMenu1 setEnabled:YES];
		[domainMenu2 setEnabled:YES];
		[domainMenu3 setEnabled:YES];
	}else{
		[noOfDomainSpells setHidden:YES];
		[domainSpells setHidden:YES];
		[spellsPerDayBox setHidden:YES];
		NSRect rect=[spellsPerDayBox frame];
		rect.size.width=236;
		[spellsPerDayBox setFrame:rect];
		[spellsPerDayBox setHidden:NO];		
		[domainMenu1 setEnabled:NO];
		[domainMenu2 setEnabled:NO];
		[domainMenu3 setEnabled:NO];
	}
	if([[obj valueForKey:@"classControlsBaseAttackAndSaves"] boolValue]){
		[totalAvailableSpells setEditable:NO];
		[totalAvailableSpells setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		NSArray *spellLevels=[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name LIKE[c] \"%@\"",[characterClass valueForKey:@"name"]]]];
		int casterLevel=-1;
		if([[obj valueForKey:@"characterClass1"] isEqualTo:characterClass]){
			casterLevel=[[obj valueForKey:@"charClassLvl1"] intValue];
		}else if([[obj valueForKey:@"characterClass2"] isEqualTo:characterClass]){
			casterLevel=[[obj valueForKey:@"charClassLvl2"] intValue];		
		}else if([[obj valueForKey:@"characterClass3"] isEqualTo:characterClass]){
			casterLevel=[[obj valueForKey:@"charClassLvl3"] intValue];
		}		
		int i;
		for(i=0;i<[spellLevels count];i++){
			[SpellMethods setupBaseAvailableSpellsForCC:characterClass
										  forSpellLevel:[spellLevels objectAtIndex:i]
										  atCasterLevel:casterLevel];
		}
	}
	if([[characterClass valueForKey:@"allSpontaneous"] boolValue]){
		[miscAvailableSpells setEditable:YES];
		[miscAvailableSpells setBackgroundColor:[NSColor whiteColor]];
		if([[obj valueForKey:@"classControlsBaseAttackAndSaves"] boolValue]){
			[baseAvailableSpells setEditable:NO];
			[baseAvailableSpells setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		}else{
			[baseAvailableSpells setEditable:YES];
			[baseAvailableSpells setBackgroundColor:[NSColor whiteColor]];
		}
	}else{
		[miscAvailableSpells setEditable:NO];
		[miscAvailableSpells setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		[baseAvailableSpells setEditable:NO];
		[baseAvailableSpells setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		[totalAvailableSpells setStringValue:@""];
		[miscAvailableSpells setStringValue:@""];
		[baseAvailableSpells setStringValue:@""];
		if([[obj valueForKey:@"classControlsBaseAttackAndSaves"] boolValue]){
			[spellsBase setEditable:NO];
			[spellsBase setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		}else{
			[spellsBase setEditable:YES];
			[spellsBase setBackgroundColor:[NSColor whiteColor]];
		}
	}
	[spellsPerDayTable reloadData];
	[self setupSpellsPerDayData];
}
-(void)processSpellbookForCharacterClass:(NSManagedObject *)characterClass
							forCharacter:(NSManagedObject *)obj{
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
		[domainSpellsSpellbookBlurb setHidden:NO];
	}else{
		[domainSpellsSpellbookBlurb setHidden:YES];		
	}
	[self setupAvailableSpells];
	[self setupCurrentCharactersSpells];
	[availableSpellsTable reloadData];
	[currentCharactersSpellsTable reloadData];
	[self checkTotalSpellsCountForClass:characterClass
						   forCharacter:obj];
	//disable/enable buttons as required.
	[self processAddToSpellbookButton];
	if([self numberOfRowsInTableView:currentCharactersSpellsTable]==0){
		[removeFromSpellbookButton setEnabled:NO];
	}else{
		[removeFromSpellbookButton setEnabled:YES];
	}	
}
-(void)reloadSpellTables{
	//NSLog(@"reloading spell tables");
	if([[charController selectedObjects] count]==0){
		return;
	}
	//check character actually casts spells.
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	if(![[[obj valueForKey:@"characterClass1"] valueForKey:@"castsSpells"] boolValue] && ![[[obj valueForKey:@"characterClass2"] valueForKey:@"castsSpells"] boolValue] && ![[[obj valueForKey:@"characterClass3"] valueForKey:@"castsSpells"] boolValue]){
		//NSLog(@"character doesn't cast spells");
		return;
	}
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	[self processingCharacter:obj
		   withCharacterClass:characterClass];
	/*[self processSpellbook];
	NSLog(@"r0.2");
	[spellsOfLevelTable reloadData];
	NSLog(@"r0.3");
	[spellsPerDayTable reloadData];
	NSLog(@"r0.35");
	[self setupSpellsPerDayData];
	NSLog(@"r0.4");
	[memorisedSpellTable reloadData];
	NSLog(@"r0.5");
	[domainSpellsOfLevelTable reloadData];
	//doing domain spells for the current spell level.
	NSLog(@"r1");
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	int level2=level-[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	NSLog(@"r3");
	//NSLog(@"obj.name=%@",[obj valueForKey:@"name"]);
	NSArray *array0=[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]];
	if([array0 count]==0){
		NSLog(@"error, %@ doesn't have any relevent spellLevels.",[obj valueForKey:@"name"]);
		return;
	}
	NSLog(@"r3.5");
	NSManagedObject *spellLevel=[array0 objectAtIndex:level2];
	NSLog(@"r4");
	NSArray *array=[[[spellLevel valueForKey:@"memorisedSpell"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"domain==1"]];
	NSLog(@"r5");
	if([array count]>0){
		[domainMemorisedTextField setStringValue:[[array objectAtIndex:0] valueForKey:@"name"]];
		[removeFromDomainSpellsButton setEnabled:YES];
	}else{
		[domainMemorisedTextField setStringValue:@""];
		[removeFromDomainSpellsButton setEnabled:NO];
	}
	NSLog(@"r6");
	//check labelling.
	[tooManySpells setHidden:YES];
	[tooFewSpells setHidden:YES];
	if([self numberOfRowsInTableView:memorisedSpellTable]<[[spellLevel valueForKey:@"totalSpells"] intValue]){
		[tooFewSpells setHidden:NO];
	}else if([self numberOfRowsInTableView:memorisedSpellTable]>[[spellLevel valueForKey:@"totalSpells"] intValue]){
		[tooManySpells setHidden:NO];
	}
	if([self numberOfRowsInTableView:spellsOfLevelTable]==0){
		[addToMemorisedSpellsButton setEnabled:NO];
	}else{
		[addToMemorisedSpellsButton setEnabled:YES];
	}
	if([self numberOfRowsInTableView:memorisedSpellTable]==0){
		[removeFromMemorisedSpellsButton setEnabled:NO];
	}else{
		[removeFromMemorisedSpellsButton setEnabled:YES];
	}
	if([self numberOfRowsInTableView:domainSpellsOfLevelTable]==0){
		[addToDomainSpellsButton setEnabled:NO];
	}else{
		[addToDomainSpellsButton setEnabled:YES];
	}
	//NSLog(@"f7");*/
}
-(void)setupAddToMemorisedButton{
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	//check if the current spell is a domain spell and a domain spell has been added already.
	NSManagedObject *spellClass=[[currentCharactersSpellClasses filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level==%d",level]]] objectAtIndex:[spellsOfLevelTable selectedRow]];
	if([[spellClass valueForKey:@"domainSpell"] boolValue]){
		if([[memorisedSpells filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"domain==1"]] count]>0){
			[addToMemorisedSpellsButton setEnabled:NO];
		}else{
			[addToMemorisedSpellsButton setEnabled:YES];
		}
	}else{
		[addToMemorisedSpellsButton setEnabled:YES];
	}
}
-(void)setupAvailableSpells{
	if(availableSpells==nil){
		availableSpells=[[NSMutableArray alloc] initWithCapacity:10];
	}
	NSString *theClass=[memorisedSpellsClass stringValue];
	if([[charController selectedObjects] count]==0)
		return;
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	[availableSpells setArray:[[characterClass valueForKey:@"spellClass"] allObjects]];
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
		NSError *error=nil;
		NSArray *domainClasses=[mObjC executeFetchRequest:[model fetchRequestFromTemplateWithName:@"domainClass" substitutionVariables:[NSDictionary dictionary]]
													error:&error];
		if(error!=nil){
			NSLog(@"error=%@",error);
		}
		NSManagedObject *domain1=nil;
		NSManagedObject *domain2=nil;
		NSManagedObject *domain3=nil;
		int i;
		for(i=0;i<[domainClasses count];i++){
			if([[[domainClasses objectAtIndex:i] valueForKey:@"name"] isEqualToString:[obj valueForKey:@"domain1"]]){
				domain1=[domainClasses objectAtIndex:i];
				if(domain2!=nil && domain3!=nil){
					break;
				}
			}
			if([[[domainClasses objectAtIndex:i] valueForKey:@"name"] isEqualToString:[obj valueForKey:@"domain2"]]){
				domain2=[domainClasses objectAtIndex:i];
				if(domain1!=nil && domain3!=nil){
					break;
				}
			}
			if([[[domainClasses objectAtIndex:i] valueForKey:@"name"] isEqualToString:[obj valueForKey:@"domain3"]]){
				domain2=[domainClasses objectAtIndex:i];
				if(domain1!=nil && domain2!=nil){
					break;
				}
			}
		}
		NSMutableSet *domainSpellClasses=[NSMutableSet setWithCapacity:10];
		if(domain1!=nil){
			[domainSpellClasses unionSet:[domain1 valueForKey:@"spellClass"]];
		}else{
			//NSLog(@"domain1 not found");
		}
		if(domain2!=nil){
			[domainSpellClasses unionSet:[domain2 valueForKey:@"spellClass"]];
		}else{
			//NSLog(@"domain2 not found");
		}
		if(domain3!=nil){
			[domainSpellClasses unionSet:[domain3 valueForKey:@"spellClass"]];
		}else{
			//NSLog(@"domain3 not found");
		}
		[availableSpells addObjectsFromArray:[domainSpellClasses allObjects]];
	}
	//NSLog(@"availableSpells.count=%d",[availableSpells count]);
	[availableSpells sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"spell.name" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"domainSpell" ascending:YES], nil]];
}
-(void)setupCurrentCharactersSpells{
	//NSLog(@"1");
	if(currentCharactersSpellClasses==nil){
		currentCharactersSpellClasses=[[NSMutableArray alloc] initWithCapacity:10];
	}
	NSString *theClass=[memorisedSpellsClass stringValue];
	if([[charController selectedObjects] count]==0)
		return;
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	[currentCharactersSpellClasses setArray:[[obj valueForKey:@"spellClass"] allObjects]];
	//NSLog(@"cc count=%d",[currentCharactersSpellClasses count]);
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
		[currentCharactersSpellClasses filterUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"aClass.name like[c] \"%@\" OR aClass.name like[c] \"%@\" OR aClass.name like[c] \"%@\" OR aClass.name like[c] \"%@\"",theClass,[obj valueForKey:@"domain1"],[obj valueForKey:@"domain2"],[obj valueForKey:@"domain3"]]]];
	}else{
		[currentCharactersSpellClasses filterUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"aClass.name like[c] \"%@\"",theClass]]];
	}
	[currentCharactersSpellClasses sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES],[[NSSortDescriptor alloc] initWithKey:@"spell.name" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"domainSpell" ascending:YES], nil]];
	//NSLog(@"2");
}
-(void)setupMemorisedSpells{
	if(memorisedSpells==nil){
		memorisedSpells=[[NSMutableArray alloc] initWithCapacity:5];
	}
	if([[charController selectedObjects] count]==0)
		return;
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	int level2=level-[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	NSManagedObject *spellLevel=[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name==\"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:level2];
	[memorisedSpells setArray:[[spellLevel valueForKey:@"memorisedSpell"] allObjects]];
	[memorisedSpells sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"castable" ascending:NO], [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"domain" ascending:YES], nil]];
	if([memorisedSpells count]==0){
		[removeFromMemorisedSpellsButton setEnabled:NO];
	}else{
		[removeFromMemorisedSpellsButton setEnabled:YES];
	}	
}
-(IBAction)setupSpellsPerDay:(id)sender{
	//NSLog(@"setting up Spells Per Day");
	if([[charController selectedObjects] count]==0){
		return;
	}
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSArray *array=[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]];
	if([array count]<=[spellsPerDayTable selectedRow]){
		NSLog(@"not enough spellLevels available");
		return;
	}
	NSManagedObject *spellLevel=[array objectAtIndex:[spellsPerDayTable selectedRow]];
	int ts=[spellsBase intValue]+[spellAbilityBonus intValue]+[spellsMiscBonus intValue];
	int spellCast=[spellsCast intValue];
	[spellTotal setIntValue:ts];
	[spellTotal2 setIntValue:ts];
	[spellsLeft setIntValue:(ts-spellCast)];
	BOOL allSpont=[[[spellLevel valueForKey:@"characterClass"] valueForKey:@"allSpontaneous"] boolValue];
	if(allSpont){
		[totalAvailableSpells setIntValue:[miscAvailableSpells intValue]+[baseAvailableSpells intValue]];
	}
	//set values up.
	[spellLevel setValue:[NSNumber numberWithInt:[spellAbilityBonus intValue]]
				  forKey:@"abilityBonusSpells"];
	[spellLevel setValue:[NSNumber numberWithInt:ts]
				  forKey:@"totalSpells"];
	[spellLevel setValue:[NSNumber numberWithInt:[spellsLeft intValue]]
				  forKey:@"spellsLeft"];
	[spellLevel setValue:[NSNumber numberWithInt:spellCast]
				  forKey:@"spellsCast"];
	[spellLevel setValue:[NSNumber numberWithInt:[spellsBase intValue]]
				  forKey:@"baseSpells"];
	[spellLevel setValue:[NSNumber numberWithInt:[spellsMiscBonus intValue]]
				  forKey:@"miscBonusSpells"];
	if(allSpont){
		[spellLevel setValue:[NSNumber numberWithInt:[totalAvailableSpells intValue]]
					  forKey:@"totalAvailableSpells"];
		[spellLevel setValue:[NSNumber numberWithInt:[miscAvailableSpells intValue]]
					  forKey:@"miscAvailableSpells"];
		[spellLevel setValue:[NSNumber numberWithInt:[baseAvailableSpells intValue]]
					  forKey:@"baseAvailableSpells"];
	}
	//check whether spell limit is reached.
	[self checkTotalSpellsCountForClass:[spellLevel valueForKey:@"characterClass"]
						   forCharacter:obj];
	[spellsPerDayTable reloadData];
}
-(void)setupSpellsPerDayData{
	if([spellsPerDayTable numberOfSelectedRows]>0){
		NSString *theClass=[memorisedSpellsClass stringValue];
		if([[charController selectedObjects] count]==0)
			return;
		NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
		NSManagedObject *characterClass;
		int casterLevel;
		if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
			characterClass=[obj valueForKey:@"characterClass1"];
			casterLevel=[[obj valueForKey:@"charClassLvl1"] intValue];
		}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
			characterClass=[obj valueForKey:@"characterClass2"];
			casterLevel=[[obj valueForKey:@"charClassLvl2"] intValue];
		}else{
			characterClass=[obj valueForKey:@"characterClass3"];
			casterLevel=[[obj valueForKey:@"charClassLvl3"] intValue];
		}
		int level=[spellsPerDayTable selectedRow]+[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
		//NSLog(@"bad at l689 ssc");
		NSManagedObject *spellLevel=[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name LIKE[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:[spellsPerDayTable selectedRow]];
		BOOL allSpont=[[characterClass valueForKey:@"allSpontaneous"] boolValue];
		//NSLog(@"done");
		[spellAbilityBonus setIntValue:[[spellLevel valueForKey:@"abilityBonusSpells"] intValue]];
		[spellTotal setIntValue:[[spellLevel valueForKey:@"totalSpells"] intValue]];
		[spellTotal2 setIntValue:[[spellLevel valueForKey:@"totalSpells"] intValue]];
		[spellsLeft setIntValue:[[spellLevel valueForKey:@"spellsLeft"] intValue]];
		[spellsCast setIntValue:[[spellLevel valueForKey:@"spellsCast"] intValue]];
		[spellsBase setIntValue:[[spellLevel valueForKey:@"baseSpells"] intValue]];
		[spellsMiscBonus setIntValue:[[spellLevel valueForKey:@"miscBonusSpells"] intValue]];
		if(allSpont){
			[totalAvailableSpells setIntValue:[[spellLevel valueForKey:@"totalAvailableSpells"] intValue]];
			[miscAvailableSpells setIntValue:[[spellLevel valueForKey:@"miscAvailableSpells"] intValue]];
			[baseAvailableSpells setIntValue:[[spellLevel valueForKey:@"baseAvailableSpells"] intValue]];
		}
		if(level==0){
			[noOfDomainSpells setIntValue:0];
		}else{
			[noOfDomainSpells setIntValue:1];
		}
	}	
}
-(void)sortTooManyAndTooFewLabelsForSpellLevel:(NSManagedObject *)spellLevel
							 forCharacterClass:(NSManagedObject *)characterClass{
	int level=[[spellLevel valueForKey:@"level"] intValue];
	//check labelling.
	[tooManySpells setHidden:YES];
	[tooFewSpells setHidden:YES];
	int noOfSpells=[[spellLevel valueForKey:@"totalSpells"] intValue];
	BOOL domainAllowed=NO;
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue] && level>0 && noOfSpells>0){
		noOfSpells++;
		domainAllowed=YES;
	}
	int memSpellsCount=[memorisedSpells count];
	if(memSpellsCount<noOfSpells){
		 if(domainAllowed && memSpellsCount+1==noOfSpells &&[[memorisedSpells filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"domain==1"]] count]==0){
			 [tooFewSpells setStringValue:@"You can memorise a domain spell too"];
		 }else{
			 [tooFewSpells setStringValue:@"You can memorise more spells"];			 
		 }
		[tooFewSpells setHidden:NO];
	}else if(memSpellsCount>noOfSpells || (domainAllowed && memSpellsCount==noOfSpells && [[memorisedSpells filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"domain==1"]] count]==0)){
		[tooManySpells setHidden:NO];
	}
}
-(IBAction)spellToSpellbook:(id)sender{
	if([[charController selectedObjects] count]==0){
		return;
	}
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	//recover spell from table.
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *characterClass;
	int sc;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		sc=1;
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		sc=2;
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		sc=3;
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	NSManagedObject *spellClass=[availableSpells objectAtIndex:[availableSpellsTable selectedRow]];
	NSMutableSet *osc=[NSMutableSet setWithCapacity:5];
	[osc setSet:[obj valueForKey:@"spellClass"]];
	[osc addObject:spellClass];
	[obj setValue:osc
		   forKey:@"spellClass"];
	[currentCharactersSpellClasses addObject:spellClass];
	[currentCharactersSpellClasses sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES],[[NSSortDescriptor alloc] initWithKey:@"spell.name" ascending:YES],nil]];
	[currentCharactersSpellsTable reloadData];
	//check whether spell limit is reached.
	[self checkTotalSpellsCountForClass:characterClass
						   forCharacter:obj];
	//setup spellbook buttons.
	[addToSpellbookButton setEnabled:NO];
	if([self numberOfRowsInTableView:currentCharactersSpellsTable]==0){
		[removeFromSpellbookButton setEnabled:NO];
	}else{
		[removeFromSpellbookButton setEnabled:YES];
	}
}
-(IBAction)spellFromSpellbook:(id)sender{
	if([[charController selectedObjects] count]==0){
		return;
	}
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSManagedObject *scToGo=[currentCharactersSpellClasses objectAtIndex:[currentCharactersSpellsTable selectedRow]];
	[currentCharactersSpellClasses removeObject:scToGo];
	NSMutableSet *osc=[NSMutableSet setWithCapacity:5];
	[osc setSet:[obj valueForKey:@"spellClass"]];
	[osc removeObject:scToGo];
	[obj setValue:osc
		   forKey:@"spellClass"];
	[currentCharactersSpellsTable reloadData];
	//getting the characterClass.
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}		
	//check whether spell limit is reached.
	[self checkTotalSpellsCountForClass:characterClass
						   forCharacter:obj];
	//check if spell that has been removed is the one selected in the current available spells table.
	NSManagedObject *spellClass2=[availableSpells objectAtIndex:[availableSpellsTable selectedRow]];
	if([scToGo isEqualTo:spellClass2]){
		[addToSpellbookButton setEnabled:YES];
	}
}
-(IBAction)spellToMemorised:(id)sender{
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	/****METAMAGIC FEATS************/
	NSManagedObject *spellClass=[[currentCharactersSpellClasses filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level==%d",level]]] objectAtIndex:[spellsOfLevelTable selectedRow]];
	NSManagedObject *tempSpellClass=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName] objectForKey:@"TempSpellClass"] insertIntoManagedObjectContext:mObjC];
	[tempSpellClass setValue:spellClass
					  forKey:@"spellClass"];
	[tempSpellClass setValue:obj
					  forKey:@"character"];
	if([metaMagicFeats isEnabled] && [metaMagicFeats state]==NSOnState){
		if(mmFeatController==nil){
			mmFeatController=[[MetaMagicFeatController alloc] init];
		}
		//NSLog(@"ctv window=%@",[characterTabView window]);
		[mmFeatController displayMetamagicFeatScreenForTempSpellClass:tempSpellClass
														modalDelegate:self
														  endSelector:@selector(metamagicSheetDidEnd:returnCode:contextInfo:)
													   modalForWindow:[characterTabView window]];
	}else{
		[self spellToMemorisedPartTwoForTempSpellClass:tempSpellClass];
	}
}
-(void)spellToMemorisedPartTwoForTempSpellClass:(NSManagedObject *)tempSpellClass{
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *spellClass=[tempSpellClass valueForKey:@"spellClass"];
	NSManagedObject *obj=[tempSpellClass valueForKey:@"character"];
	NSManagedObject *characterClass;
	if([theClass isEqualTo:[obj valueForKey:@"charClassName1"]]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([theClass isEqualTo:[obj valueForKey:@"charClassName2"]]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	int level2=level-[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	int level2Original=level2;//see if the level2 value has been changed.
	NSSet *feats=[tempSpellClass valueForKey:@"featsTemp"];
	if(feats!=nil){
		//add level2 values from the feats.
		int i;
		NSArray *array=[feats allObjects];
		for(i=0;i<[array count];i++){
			NSManagedObject *feat=[array objectAtIndex:i];
			level2=level2+[[feat valueForKey:@"spellLevelMod"] intValue];
			if([[feat valueForKey:@"spellKey"] isEqualToString:@"Caster Level"]){
				if([FeatActions xValueInUse:feat]){
					level2=level2+[[feat valueForKey:@"xValue"] intValue];
				}else{
					level2=level2+[[feat valueForKey:@"spellMod"] intValue];
				}
			}
		}
	}
	[mObjC deleteObject:tempSpellClass];
	NSManagedObject *spellLevel=[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name==\"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:level2];
	NSManagedObject *mSpell=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"MemorisedSpell"]
									 insertIntoManagedObjectContext:mObjC];
	NSString *name=[[spellClass valueForKey:@"spell"] valueForKey:@"name"];
		if(feats==nil || [feats count]==0){
			[mSpell setValue:name
					  forKey:@"name"];
		}else{
			[mSpell setValue:[name stringByAppendingString:@"*"]
					  forKey:@"name"];
			[mSpell setValue:feats
					  forKey:@"feat"];
		}
	[mSpell setValue:spellClass
			  forKey:@"spellClass"];
	[mSpell setValue:spellLevel
			  forKey:@"spellLevel"];
	if([[spellClass valueForKey:@"domainSpell"] boolValue]){
		[mSpell setValue:[NSNumber numberWithBool:YES]
				  forKey:@"domain"];
	}
	//level changed.
	if(level2!=level2Original){
		[memorisedSpellsTabs selectTabViewItemAtIndex:level2];
		return;
	}
	if([[spellClass valueForKey:@"domainSpell"] boolValue]){
		[addToMemorisedSpellsButton setEnabled:NO];
	}
	[self setupMemorisedSpells];
	[memorisedSpellTable reloadData];
	[self sortTooManyAndTooFewLabelsForSpellLevel:spellLevel
								forCharacterClass:characterClass];
	if([self numberOfRowsInTableView:memorisedSpellTable]==0){
		[removeFromMemorisedSpellsButton setEnabled:NO];
	}else{
		[removeFromMemorisedSpellsButton setEnabled:YES];
	}
}
-(IBAction)spellFromMemorised:(id)sender{
	if([[charController selectedObjects] count]==0)
		return;
	int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
	NSString *theClass=[memorisedSpellsClass stringValue];
	NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
	NSManagedObject *characterClass;
	if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass1"];
	}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
		characterClass=[obj valueForKey:@"characterClass2"];
	}else{
		characterClass=[obj valueForKey:@"characterClass3"];
	}
	int level2=level-[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	//NSLog(@"before bad l189 ssc");
	NSManagedObject *spellLevel=[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:level2];
	NSManagedObject *memSpell=[[[[spellLevel valueForKey:@"memorisedSpell"] allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"castable" ascending:NO], [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"domain" ascending:YES], nil]] objectAtIndex:[memorisedSpellTable selectedRow]];
	//NSLog(@"done");
	[memSpell setValue:nil
				forKey:@"spellLevel"];
	[memSpell setValue:nil
				forKey:@"spellClass"];
	[mObjC deleteObject:memSpell];
	[self setupMemorisedSpells];
	[memorisedSpellTable reloadData];
	if([spellsOfLevelTable numberOfRows]==0){
		[addToMemorisedSpellsButton setEnabled:NO];
	}else{
		[self setupAddToMemorisedButton];
	}
	[self sortTooManyAndTooFewLabelsForSpellLevel:spellLevel
								forCharacterClass:characterClass];
	if([self numberOfRowsInTableView:memorisedSpellTable]==0){
		[removeFromMemorisedSpellsButton setEnabled:NO];
	}else{
		[removeFromMemorisedSpellsButton setEnabled:YES];
	}
}
-(void)metamagicSheetDidEnd:(NSWindow *)sheet
				 returnCode:(int)returnCode
				contextInfo:(NSManagedObject *)tempSpellClass{
	if(returnCode==1){
		[mObjC deleteObject:tempSpellClass];
		return;
	}
	[self spellToMemorisedPartTwoForTempSpellClass:tempSpellClass];
}
#pragma mark -
#pragma mark Global Options
#pragma mark 
-(void)setupDomainsList{
	//NSLog(@"setting up domains");
	if(mObjC==nil){
		mObjC=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
	}
	if(model==nil){
		model=[[mObjC persistentStoreCoordinator] managedObjectModel];
	}
	NSMutableArray *names=[NSMutableArray arrayWithCapacity:5];
	[names setArray:[[mObjC executeFetchRequest:[model fetchRequestFromTemplateWithName:@"domainClass" substitutionVariables:[NSDictionary dictionary]] error:nil]  valueForKey:@"name"]];
	[names sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
	[names insertObject:@"Choose..." atIndex:0];
	[names insertObject:@"" atIndex:1];
	//NSLog(@"names.count=%d",[names count]);
	[domainMenu1 removeAllItems];
	[domainMenu2 removeAllItems];
	[domainMenu3 removeAllItems];
	[domainMenu1 addItemsWithTitles:names];
	[domainMenu2 addItemsWithTitles:names];
	[domainMenu3 addItemsWithTitles:names];
	//[domainsController setAutomaticallyPreparesContent:YES];
}
-(IBAction)domain1Setup:(id)sender{
	//NSLog(@"domain1 setup");
	if([[charController selectedObjects] count]==0){
		return;
	}
	[[[charController selectedObjects] objectAtIndex:0] setValue:[domainMenu1 titleOfSelectedItem]
														  forKey:@"domain1"];
}
-(IBAction)domain2Setup:(id)sender{
	//NSLog(@"domain2 setup");
	if([[charController selectedObjects] count]==0){
		return;
	}
	[[[charController selectedObjects] objectAtIndex:0] setValue:[domainMenu2 titleOfSelectedItem]
														  forKey:@"domain2"];
}
-(IBAction)domain3Setup:(id)sender{
	//NSLog(@"domain2 setup");
	if([[charController selectedObjects] count]==0){
		return;
	}
	[[[charController selectedObjects] objectAtIndex:0] setValue:[domainMenu3 titleOfSelectedItem]
														  forKey:@"domain3"];
}
-(IBAction)spellSaveModSetup:(id)sender{
	if([[charController selectedObjects] count]==0){
		return;
	}
	[[[charController selectedObjects] objectAtIndex:0] setValue:[NSNumber numberWithInt:[spellSaveModTF intValue]]
														  forKey:@"spellSaveModifier"];
}
-(IBAction)spellPenetrationSetup:(id)sender{
	if([[charController selectedObjects] count]==0){
		return;
	}
	[[[charController selectedObjects] objectAtIndex:0] setValue:[NSNumber numberWithInt:[spellPenetrationTF intValue]]
														  forKey:@"spellPenetration"];
}
#pragma mark -
#pragma mark Random
#pragma mark 
-(void)processMagicView:(NSTabViewItem *)magicView
			   forClass:(NSManagedObject *)characterClass
				forChar:(NSManagedObject *)obj{
	[magicView setView:spellsAvailableView];
	[self createSpellLevels:characterClass
					forChar:obj];
	[memorisedSpellsClass setStringValue:[characterClass valueForKey:@"name"]];
	if([[characterClass valueForKey:@"allSpontaneous"] boolValue]){
		if([spellOptionsTabs numberOfTabViewItems]==3){
			if([[spellOptionsTabs selectedTabViewItem] isEqualTo:[spellOptionsTabs tabViewItemAtIndex:1]]){
				[spellOptionsTabs selectTabViewItemAtIndex:0];
				//we could record that memorised was selected so we go back if mem added later.
				memorisedWasSelected=YES;
			}
			[spellOptionsTabs removeTabViewItem:[spellOptionsTabs tabViewItemAtIndex:1]];	
		}
	}else{
		[miscAvailableSpells setEditable:NO];
		[miscAvailableSpells setBackgroundColor:[NSColor colorWithDeviceRed:0.93 green:0.93 blue:0.93 alpha:1.0]];
		[totalAvailableSpells setStringValue:@""];
		[miscAvailableSpells setStringValue:@""];
		[baseAvailableSpells setStringValue:@""];
		if([spellOptionsTabs numberOfTabViewItems]==2){
			NSTabViewItem *tabViewItem=[[[NSTabViewItem alloc] init] autorelease];
			[tabViewItem setLabel:@"Memorised Spells"];
			[tabViewItem setView:memorisedSpellsTotalView];
			[spellOptionsTabs insertTabViewItem:tabViewItem
										atIndex:1];
			if(memorisedWasSelected){
				[spellOptionsTabs selectTabViewItemAtIndex:1];
			}
		}	
	}
	[self processingCharacter:obj
		   withCharacterClass:characterClass];
}
-(void)checkTotalSpellsCountForClass:(NSManagedObject *)characterClass
						forCharacter:(NSManagedObject *)obj{
	[tooFewSpellsTF setHidden:YES];
	[tooManySpellsTF setHidden:YES];
	if(![[characterClass valueForKey:@"allSpontaneous"] boolValue]){
		return;
	}
	NSArray *spellLevels=[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",[characterClass valueForKey:@"name"]]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]];
	int i;
	NSMutableString *tooFew=[NSMutableString stringWithCapacity:15];
	NSMutableString *tooMany=[NSMutableString stringWithCapacity:15];
	[tooFew setString:@"Too few level"];
	[tooMany setString:@"Too many level"];
	int minCount=[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	for(i=0;i<[spellLevels count];i++){
		NSManagedObject *spellLevel=[spellLevels objectAtIndex:i];
		int noOfSpells=[[currentCharactersSpellClasses filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level==%d",i]]] count];
		int whatTheTotalShouldBe=[[spellLevel valueForKey:@"totalAvailableSpells"] intValue];
		if(noOfSpells<whatTheTotalShouldBe){
			if(![tooFew isEqualToString:@"Too few level"]){
				[tooFew appendString:@","];
			}
			[tooFew appendFormat:@" %d",i+minCount];
		}else if(noOfSpells>whatTheTotalShouldBe){
			if(![tooMany isEqualToString:@"Too many level"]){
				[tooMany appendString:@","];
			}
			[tooMany appendFormat:@" %d",i+minCount];
		}
	}
	if(![tooFew isEqualToString:@"Too few level"]){
		[tooFew appendString:@" spells added."];
		[tooFewSpellsTF setStringValue:tooFew];
		[tooFewSpellsTF setHidden:NO];
	}
	if(![tooMany isEqualToString:@"Too many level"]){
		[tooMany appendString:@" spells added."];
		[tooManySpellsTF setStringValue:tooMany];
		[tooManySpellsTF setHidden:NO];
	}
}
-(void)setupMemorised:(NSTabView *)tabView
			  forChar:(NSManagedObject *)obj
			 forClass:(NSManagedObject *)characterClass{
	if([[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
		[domainSpellsBlurb setHidden:NO];
	}else{
		[domainSpellsBlurb setHidden:YES];
	}
	NSTabViewItem *tabViewItem=[tabView selectedTabViewItem];
	[self setupCurrentCharactersSpells];
	int level=[[tabViewItem label] intValue];
	//NSLog(@"number of tab view items=%d",[tabView numberOfTabViewItems]);
	int newLow=[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
	int newHigh=[[characterClass valueForKey:@"maximumSpellLevel"] intValue];
	int currentLow=[[[tabView tabViewItemAtIndex:0] label] intValue];
	int currentHigh=[[[tabView tabViewItemAtIndex:[tabView numberOfTabViewItems]-1] label] intValue];
	//NSLog(@"nl=%d, nh=%d, cl=%d, ch=%d",newLow,newHigh,currentLow,currentHigh);
	if(newLow!=currentLow || newHigh!=currentHigh){
		//check correct number of tabs visible.
		int i;
		[tabView setDelegate:nil];
		for(i=0;i<currentHigh-currentLow;i++){
			[tabView removeTabViewItem:[tabView tabViewItemAtIndex:0]];
		}
		[[tabView tabViewItemAtIndex:0] setLabel:[NSString stringWithFormat:@"%d",newLow]];
		for(i=0;i<newHigh-newLow;i++){
			NSTabViewItem *tabViewItem=[[[NSTabViewItem alloc] init] autorelease];
			[tabViewItem setLabel:[NSString stringWithFormat:@"%d",i+1+newLow]];
			[tabView addTabViewItem:tabViewItem];
		}
		if(level+newLow>=0 && level+newLow<[tabView numberOfTabViewItems]){
			[tabView selectTabViewItemAtIndex:level+newLow];
		}
		[tabView setDelegate:self];	
	}
	tabViewItem=[tabView selectedTabViewItem];
	level=[[tabViewItem label] intValue];
	//check metamagic feats.
	if([[[[obj valueForKey:@"feats"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"type==2 AND active==1"]] count]==0){
		[metaMagicFeats setEnabled:NO];
	}else{
		[metaMagicFeats setEnabled:YES];
	}
	if([[spellsOfLevelTable tableColumns] count]==0){
		return;
	}
	NSTableColumn *tc=[[spellsOfLevelTable tableColumns] objectAtIndex:0];
	NSTableHeaderCell *header=[tc headerCell];
	[header setStringValue:[NSString stringWithFormat:@"All Spells of Level %d",level]];
	[tc setHeaderCell:header];
	//[spellsOfLevelTable reloadData];//try reloading to see if helps.
	NSArray *array0=[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",[characterClass valueForKey:@"name"]]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]];
	if([array0 count]==0){
		NSLog(@"error, %@ doesn't have any relevent spellLevels.",[obj valueForKey:@"name"]);
		return;
	}
	NSManagedObject *spellLevel=[array0 objectAtIndex:level-newLow];
	//set up table data and stuff.
	//NSLog(@"to set view");
	[tabViewItem setView:memorisedSpellView];
	//NSLog(@"view set");
	//[self reloadSpellTables];
	[spellsOfLevelTable reloadData];
	[self setupMemorisedSpells];
	[memorisedSpellTable reloadData];
	if([spellsOfLevelTable numberOfRows]==0){
		[addToMemorisedSpellsButton setEnabled:NO];
	}else{
		[self setupAddToMemorisedButton];
	}
	[self sortTooManyAndTooFewLabelsForSpellLevel:spellLevel
								forCharacterClass:characterClass];
}
-(BOOL)createSpellLevels:(NSManagedObject *)characterClass
				 forChar:(NSManagedObject *)obj{
	//NSLog(@"creating spell Levels");
	//NSLog(@"1");
	//check if spell levels already exsist.
	//NSLog(@"
	NSArray *spellLevels=[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"characterClass==%@", characterClass]];
	if([spellLevels count]==0){
		int i=[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
		int spellLevel=[[characterClass valueForKey:@"maximumSpellLevel"] intValue];
		for(i;i<=spellLevel;i++){

			//NSLog(@"b");
			NSManagedObject *sLevel=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"SpellLevel"]
											 insertIntoManagedObjectContext:mObjC];
			//NSLog(@"a");
			[sLevel setValue:[NSNumber numberWithInt:i]
					  forKey:@"level"];
			[sLevel setValue:characterClass
					  forKey:@"characterClass"];
			[sLevel setValue:obj
					  forKey:@"character"];
		}
	}
	if([spellsPerDayTable selectedRow]==-1){
		[spellsPerDayTable selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
	}
	//NSLog(@"spell levels made");
	if([[characterClass valueForKey:@"keyAttribute"] isEqualToString:@"Intelligence"]){
		[AbilityChanged intelligenceChangedForChar:obj];
	}else if([[characterClass valueForKey:@"keyAttribute"] isEqualToString:@"Wisdom"]){
		[AbilityChanged wisdomChangedForChar:obj];		
	}else if([[characterClass valueForKey:@"keyAttribute"] isEqualToString:@"Charisma"]){
		[AbilityChanged charismaChangedForChar:obj];
	}
	return YES;
}
-(void)tableViewSelectionDidChange:(NSNotification *)notification{
	//NSLog(@"spell table selection changed");
	if([[notification object] isEqualTo:spellsPerDayTable]){
		[self setupSpellsPerDayData];
	}else if([[notification object] isEqualTo:spellsOfLevelTable]){
		if([spellsOfLevelTable numberOfRows]==0){
			[addToMemorisedSpellsButton setEnabled:NO];
		}else{
			[self setupAddToMemorisedButton];
		}
	}else if([[notification object] isEqualTo:memorisedSpellTable]){
		if([self numberOfRowsInTableView:memorisedSpellTable]==0){
			[removeFromMemorisedSpellsButton setEnabled:NO];
		}else{
			[removeFromMemorisedSpellsButton setEnabled:YES];
		}
	}else if([[notification object] isEqualTo:availableSpellsTable]){
		[self processAddToSpellbookButton];
	}else if([[notification object] isEqualTo:currentCharactersSpellsTable]){
		if([self numberOfRowsInTableView:currentCharactersSpellsTable]==0){
			[removeFromSpellbookButton setEnabled:NO];
		}else{
			[removeFromSpellbookButton setEnabled:YES];
		}
	}
}
	
- (void)tabView:(NSTabView *)tabView
didSelectTabViewItem:(NSTabViewItem *)tabViewItem{
	//NSLog(@"spell tabs changed");
	if([tabView isEqualTo:memorisedSpellsTabs]){
		if([[charController selectedObjects] count]!=0){
			NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
			NSString *theClass=[memorisedSpellsClass stringValue];
			NSManagedObject *characterClass;
			if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
				characterClass=[obj valueForKey:@"characterClass1"];
			}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
				characterClass=[obj valueForKey:@"characterClass2"];
			}else{
				characterClass=[obj valueForKey:@"characterClass3"];
			}			
			[self setupMemorised:tabView
						 forChar:obj
						forClass:characterClass];
		}
	}else if([tabView isEqualTo:spellOptionsTabs]){
		memorisedWasSelected=NO;
		NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
		NSString *theClass=[memorisedSpellsClass stringValue];
		NSManagedObject *characterClass;
		if([[obj valueForKey:@"charClassName1"] isEqualToString:theClass]){
			characterClass=[obj valueForKey:@"characterClass1"];
		}else if([[obj valueForKey:@"charClassName2"] isEqualToString:theClass]){
			characterClass=[obj valueForKey:@"characterClass2"];
		}else{
			characterClass=[obj valueForKey:@"characterClass3"];
		}
		[self processingCharacter:obj
			   withCharacterClass:characterClass];
	}
}
-(BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(int)rowIndex{
	return YES;
}
#pragma mark-
#pragma mark Table Stuff
#pragma mark 
-(int)numberOfRowsInTableView:(NSTableView *)aTableView{
	//NSLog(@"spell table no of rows changed");
	if([aTableView isEqualTo:availableSpellsTable]){
		return [availableSpells count];
	}else if([aTableView isEqualTo:currentCharactersSpellsTable]){
		return [currentCharactersSpellClasses count];
	}else if([aTableView isEqualTo:spellsOfLevelTable]){
		int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
		return [[currentCharactersSpellClasses filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level==%d",level]]] count];
	}else if([aTableView isEqualTo:spellsPerDayTable]){
		//NSLog(@"hi spd rows");
		NSString *theClass=[memorisedSpellsClass stringValue];
		if([[charController selectedObjects] count]==0)
			return 0;
		int c=[[[[[[charController selectedObjects] objectAtIndex:0] valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name==\"%@\"",theClass]]] count];
		//NSLog(@"bye spd rows");
		return c;
	}else if([aTableView isEqualTo:memorisedSpellTable]){
		return [memorisedSpells count];
	}/*else if([aTableView isEqualTo:metaMagicTable]){
		if([[charController selectedObjects] count]==0)
			return 0;
		NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
		return [[[[obj valueForKey:@"feats"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"type==2 AND active==1"]] count];
	}*/
	return 0;
}
-(id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
		   row:(int)row{
	//NSLog(@"spell table data changed");
	if([aTableView isEqualTo:availableSpellsTable]){
		NSManagedObject *spellClass=[availableSpells objectAtIndex:row];
		NSString *value;
		if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:0]]){
			value=[NSString stringWithFormat:@"%@",[spellClass valueForKey:@"level"]];
		}else{
			value=[[spellClass valueForKey:@"spell"] valueForKey:@"name"];
		}
		//check if domain spell or not
		NSAttributedString *toReturn;
		if([[spellClass valueForKey:@"domainSpell"] boolValue]){
			toReturn=[[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.79 green:0.152 blue:0.0 alpha:1.0] forKey:NSForegroundColorAttributeName]];
		}else{
			toReturn=[[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]];	
		}
		return toReturn;
	}else if([aTableView isEqualTo:currentCharactersSpellsTable]){
		//NSLog(@"tvo 1");
		NSManagedObject *spellClass=[currentCharactersSpellClasses objectAtIndex:row];
		//NSLog(@"spell name=%@",[spell valueForKey:@"name"]);
		NSString *value;
		if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:0]]){
			value=[NSString stringWithFormat:@"%@",[spellClass valueForKey:@"level"]];
		}else{
			value=[[spellClass valueForKey:@"spell"] valueForKey:@"name"];
		}
		//check if domain spell or not
		NSAttributedString *toReturn;
		if([[spellClass valueForKey:@"domainSpell"] boolValue]){
			toReturn=[[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.79 green:0.152 blue:0.0 alpha:1.0] forKey:NSForegroundColorAttributeName]];	
		}else{
			toReturn=[[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]];	
		}
		return toReturn;
		//return @"Poo";
	}else if([aTableView isEqualTo:spellsOfLevelTable]){
		int level=[[[memorisedSpellsTabs selectedTabViewItem] label] intValue];
		NSManagedObject *spellClass=[[currentCharactersSpellClasses filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level==%d",level]]] objectAtIndex:row];
		NSString *value=[[spellClass valueForKey:@"spell"] valueForKey:@"name"];
		//NSLog(@"tvo 2");
		if([[spellClass valueForKey:@"domainSpell"] boolValue]){
			return [[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.79 green:0.152 blue:0.0 alpha:1.0] forKey:NSForegroundColorAttributeName]];	
		}else{
			return [[NSAttributedString alloc] initWithString:value attributes:[NSDictionary dictionaryWithObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]];	
		}
	}else if([aTableView isEqualTo:spellsPerDayTable]){
		//NSLog(@"hi spd object");
		NSString *theClass=[memorisedSpellsClass stringValue];
		if([[charController selectedObjects] count]==0)
			return nil;
		NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
		id toReturn;
		if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:0]]){
			toReturn=[[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:row] valueForKey:@"level"];
		}else if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:1]]){
			toReturn=[[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c]\"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:row] valueForKey:@"totalSpells"];
		}else{
			toReturn=[[[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\"",theClass]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]] objectAtIndex:row] valueForKey:@"spellsLeft"];
		}
		//NSLog(@"bye spd objects");
		return toReturn;
	}else if([aTableView isEqualTo:memorisedSpellTable]){
		NSManagedObject *memSpell=[memorisedSpells objectAtIndex:row];
		//set text colour.
		NSAttributedString *name;
		if(![[memSpell valueForKey:@"castable"] boolValue]){
			name=[[NSAttributedString alloc] initWithString:[memSpell valueForKey:@"name"] attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.4 green:0.4 blue:0.4 alpha:1.0] forKey:NSForegroundColorAttributeName]];			
		}else{
			if([[memSpell valueForKey:@"domain"] boolValue]){
				name=[[NSAttributedString alloc] initWithString:[memSpell valueForKey:@"name"] attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.79 green:0.152 blue:0.0 alpha:1.0] forKey:NSForegroundColorAttributeName]];
			}else{
				name=[[NSAttributedString alloc] initWithString:[memSpell valueForKey:@"name"] attributes:[NSDictionary dictionaryWithObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]];
			}
			
		}
		return name;
	}/*else if([aTableView isEqualTo:metaMagicTable]){
		if([[charController selectedObjects] count]==0)
			return nil;
		NSManagedObject *obj=[[charController selectedObjects] objectAtIndex:0];
		NSManagedObject *feat=[[[[obj valueForKey:@"feats"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"type==2 AND active==1"]] objectAtIndex:row];
		if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:0]]){
			return [feat valueForKey:@"name"];
		}
	}*/
	return nil;
}
@end
